﻿/* 
* Copyright (c) 2010, The University of Texas at Austin
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, 
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, 
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, 
* this list of conditions and the following disclaimer in the documentation and/or other materials 
* provided with the distribution.
*
* Neither the name of The University of Texas at Austin nor the names of its contributors may be 
* used to endorse or promote products derived from this software without specific prior written 
* permission.
* 
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

using System.Collections.Generic;
using System.Windows;
using System.Windows.Media;
using Bio.Views.Structure.Editor.Internal.Rendering;

namespace Bio.Views.Structure.Editor.Internal.Editing
{
    public class StructureElementPropertyChangeSet
    {
        public int ChangesRecorded { get { return _changes.Count; } }

        public bool HasNucleotideFontFamilyChange { get { return _changes.ContainsKey(StructureElementVisualComponentPropertyContext.NucleotideFontFamilyPropertyKey); } }
        public bool HasNucleotideFontStyleChange { get { return _changes.ContainsKey(StructureElementVisualComponentPropertyContext.NucleotideFontStylePropertyKey); } }
        public bool HasNucleotideFontWeightChange { get { return _changes.ContainsKey(StructureElementVisualComponentPropertyContext.NucleotideFontWeightPropertyKey); } }
        public bool HasNucleotideFontSizeChange { get { return _changes.ContainsKey(StructureElementVisualComponentPropertyContext.NucleotideFontSizePropertyKey); } }
        public bool HasNucleotideFillChange { get { return _changes.ContainsKey(StructureElementVisualComponentPropertyContext.NucleotideFillPropertyKey); } }
        public bool HasNucleotideSubstitutionChange { get { return _changes.ContainsKey(StructureElementVisualComponentPropertyContext.NucleotideSubstitutionPropertyKey); } }
        public bool HasIsNucleotideSubstitutedChange { get { return _changes.ContainsKey(StructureElementVisualComponentPropertyContext.IsNucleotideSubstitutedPropertyKey); } }
        public bool HasNucleotideCircleDiameterChange { get { return _changes.ContainsKey(StructureElementVisualComponentPropertyContext.NucleotideCircleDiameterPropertyKey); } }
        public bool HasNucleotideCircleEdgeThicknessChange { get { return _changes.ContainsKey(StructureElementVisualComponentPropertyContext.NucleotideCircleEdgeThicknessPropertyKey); } }
        public bool HasNucleotideCircleIsFilledChange { get { return _changes.ContainsKey(StructureElementVisualComponentPropertyContext.NucleotideCircleIsFilledPropertyKey); } }
        public bool HasNucleotideCircleFillChange { get { return _changes.ContainsKey(StructureElementVisualComponentPropertyContext.NucleotideCircleFillPropertyKey); } }
        public bool HasNucleotideCircleStrokeChange { get { return _changes.ContainsKey(StructureElementVisualComponentPropertyContext.NucleotideCircleStrokePropertyKey); } }
        public bool HasNucleotideRenderingStyleChange { get { return _changes.ContainsKey(StructureElementVisualComponentPropertyContext.NucleotideRenderingStylePropertyKey); } }
        public bool HasBasePairConnectorIsFilledChange { get { return _changes.ContainsKey(StructureElementVisualComponentPropertyContext.BasePairConnectorIsFilledPropertyKey); } }
        public bool HasBasePairConnectorIsVisibleChange { get { return _changes.ContainsKey(StructureElementVisualComponentPropertyContext.BasePairConnectorIsVisiblePropertyKey); } }
        public bool HasBasePairConnectorFillChange { get { return _changes.ContainsKey(StructureElementVisualComponentPropertyContext.BasePairConnectorFillPropertyKey); } }
        public bool HasBasePairConnectorStrokeChange { get { return _changes.ContainsKey(StructureElementVisualComponentPropertyContext.BasePairConnectorStrokePropertyKey); } }
        public bool HasBasePairConnectorSizeChange { get { return _changes.ContainsKey(StructureElementVisualComponentPropertyContext.BasePairConnectorSizePropertyKey); } }
        public bool HasBasePairConnectorStrokeThicknessChange { get { return _changes.ContainsKey(StructureElementVisualComponentPropertyContext.BasePairConnectorStrokeThicknessPropertyKey); } }
        public bool HasBasePairConnectorRenderingStyleChange { get { return _changes.ContainsKey(StructureElementVisualComponentPropertyContext.BasePairConnectorRenderingStylePropertyKey); } }

        public char? NucleotideSubstitutionChange {
            get { return (HasNucleotideSubstitutionChange) ? _changes[StructureElementVisualComponentPropertyContext.NucleotideSubstitutionPropertyKey] as char? : null; }
        }

        public bool? IsNucleotideSubstitutedChange {
            get { return (HasIsNucleotideSubstitutedChange) ? _changes[StructureElementVisualComponentPropertyContext.IsNucleotideSubstitutedPropertyKey] as bool? : null; }
        }

        public NucleotideRenderingMode? NucleotideRenderingStyleChange {
            get { return (HasNucleotideRenderingStyleChange) ? _changes[StructureElementVisualComponentPropertyContext.NucleotideRenderingStylePropertyKey] as NucleotideRenderingMode? : null; }
        }

        public FontFamily NucleotideFontFamilyChange  { 
            get { return (HasNucleotideFontFamilyChange) ? _changes[StructureElementVisualComponentPropertyContext.NucleotideFontFamilyPropertyKey] as FontFamily : null; } 
        }

        public FontStyle? NucleotideFontStyleChange { 
            get { return (HasNucleotideFontStyleChange) ? _changes[StructureElementVisualComponentPropertyContext.NucleotideFontStylePropertyKey] as FontStyle? : null; } 
        }

        public FontWeight? NucleotideFontWeightChange {
            get { return (HasNucleotideFontWeightChange) ? _changes[StructureElementVisualComponentPropertyContext.NucleotideFontWeightPropertyKey] as FontWeight? : null; }
        }

        public double? NucleotideFontSizeChange {
            get { return (HasNucleotideFontSizeChange) ? _changes[StructureElementVisualComponentPropertyContext.NucleotideFontSizePropertyKey] as double? : null; }
        }

        public Brush NucleotideFillChange {
            get { return (HasNucleotideFillChange) ? _changes[StructureElementVisualComponentPropertyContext.NucleotideFillPropertyKey] as Brush : null; }
        }

        public double? NucleotideCircleDiameterChange {
           get { return (HasNucleotideCircleDiameterChange) ? _changes[StructureElementVisualComponentPropertyContext.NucleotideCircleDiameterPropertyKey] as double? : null; }
        }

        public double? NucleotideCircleEdgeThicknessChange {
            get { return (HasNucleotideCircleEdgeThicknessChange) ? _changes[StructureElementVisualComponentPropertyContext.NucleotideCircleEdgeThicknessPropertyKey] as double? : null; }
        }

        public bool? NucleotideCircleIsFilledChange {
            get { return (HasNucleotideCircleIsFilledChange) ? _changes[StructureElementVisualComponentPropertyContext.NucleotideCircleIsFilledPropertyKey] as bool? : null; }
        }

        public Brush NucleotideCircleFillChange {
            get { return (HasNucleotideCircleFillChange) ? _changes[StructureElementVisualComponentPropertyContext.NucleotideCircleFillPropertyKey] as Brush : null; }
        }

        public Brush NucleotideCircleStrokeChange {
            get { return (HasNucleotideCircleStrokeChange) ? _changes[StructureElementVisualComponentPropertyContext.NucleotideCircleStrokePropertyKey] as Brush : null; }
        }

        public bool? BasePairConnectorIsFilledChange {
            get { return (HasBasePairConnectorIsFilledChange) ? _changes[StructureElementVisualComponentPropertyContext.BasePairConnectorIsFilledPropertyKey] as bool? : null; }
        }

        public bool? BasePairConnectorIsVisibleChange {
            get { return (HasBasePairConnectorIsVisibleChange) ? _changes[StructureElementVisualComponentPropertyContext.BasePairConnectorIsVisiblePropertyKey] as bool? : null; }
        }

        public Brush BasePairConnectorFillChange {
            get { return (HasBasePairConnectorFillChange) ? _changes[StructureElementVisualComponentPropertyContext.BasePairConnectorFillPropertyKey] as Brush : null; }
        }

        public Brush BasePairConnectorStrokeChange {
            get { return (HasBasePairConnectorStrokeChange) ? _changes[StructureElementVisualComponentPropertyContext.BasePairConnectorStrokePropertyKey] as Brush : null; }
        }

        public double? BasePairConnectorSizeChange {
            get { return (HasBasePairConnectorSizeChange) ? _changes[StructureElementVisualComponentPropertyContext.BasePairConnectorSizePropertyKey] as double? : null; }
        }

        public double? BasePairConnectorStrokeThicknessChange {
            get { return (HasBasePairConnectorStrokeThicknessChange) ? _changes[StructureElementVisualComponentPropertyContext.BasePairConnectorStrokeThicknessPropertyKey] as double? : null; }
        }

        public BasePairConnectorRenderingMode? BasePairConnectorRenderingStyleChange {
            get { return (HasBasePairConnectorRenderingStyleChange) ? _changes[StructureElementVisualComponentPropertyContext.BasePairConnectorRenderingStylePropertyKey] as BasePairConnectorRenderingMode? : null; }
        }

        public void MarkNucleotideFontFamilyChange(FontFamily value)
        {
            if (!HasNucleotideFontFamilyChange)
                _changes.Add(StructureElementVisualComponentPropertyContext.NucleotideFontFamilyPropertyKey, value);
            else
                _changes[StructureElementVisualComponentPropertyContext.NucleotideFontFamilyPropertyKey] = value;
        }

        public void ClearNucleotideFontFamilyChange()
        {
            if (HasNucleotideFontFamilyChange)
                _changes.Remove(StructureElementVisualComponentPropertyContext.NucleotideFontFamilyPropertyKey);
        }

        public void MarkNucleotideFontStyleChange(FontStyle? value)
        {
            if (!HasNucleotideFontStyleChange)
                _changes.Add(StructureElementVisualComponentPropertyContext.NucleotideFontStylePropertyKey, value);
            else
                _changes[StructureElementVisualComponentPropertyContext.NucleotideFontStylePropertyKey] = value;
        }

        public void ClearNucleotideFontStyleChange()
        {
            if (HasNucleotideFontStyleChange)
                _changes.Remove(StructureElementVisualComponentPropertyContext.NucleotideFontStylePropertyKey);
        }

        public void MarkNucleotideFontWeightChange(FontWeight? value)
        {
            if (!HasNucleotideFontWeightChange)
                _changes.Add(StructureElementVisualComponentPropertyContext.NucleotideFontWeightPropertyKey, value);
            else
                _changes[StructureElementVisualComponentPropertyContext.NucleotideFontWeightPropertyKey] = value;
        }

        public void ClearNucleotideFontWeightChange()
        {
            if (HasNucleotideFontWeightChange)
                _changes.Remove(StructureElementVisualComponentPropertyContext.NucleotideFontWeightPropertyKey);
        }

        public void MarkNucleotideFontSizeChange(double? value)
        {
            if (!HasNucleotideFontSizeChange)
                _changes.Add(StructureElementVisualComponentPropertyContext.NucleotideFontSizePropertyKey, value);
            else
                _changes[StructureElementVisualComponentPropertyContext.NucleotideFontSizePropertyKey] = value;
        }

        public void ClearNucleotideFontSizeChange()
        {
            if (HasNucleotideFontSizeChange)
                _changes.Remove(StructureElementVisualComponentPropertyContext.NucleotideFontSizePropertyKey);
        }

        public void MarkNucleotideFillChange(Brush value)
        {
            if (!HasNucleotideFillChange)
                _changes.Add(StructureElementVisualComponentPropertyContext.NucleotideFillPropertyKey, value);
            else
                _changes[StructureElementVisualComponentPropertyContext.NucleotideFillPropertyKey] = value;
        }

        public void ClearNucleotideFillChange()
        {
            if (HasNucleotideFillChange)
                _changes.Remove(StructureElementVisualComponentPropertyContext.NucleotideFillPropertyKey);
        }

        public void MarkNucleotideSubstitutionChange(char? value)
        {
            if (!HasNucleotideSubstitutionChange)
                _changes.Add(StructureElementVisualComponentPropertyContext.NucleotideSubstitutionPropertyKey, value);
            else
                _changes[StructureElementVisualComponentPropertyContext.NucleotideSubstitutionPropertyKey] = value;
        }

        public void ClearNucleotideSubsitutionChange()
        {
            if (HasNucleotideSubstitutionChange)
                _changes.Remove(StructureElementVisualComponentPropertyContext.NucleotideSubstitutionPropertyKey);
        }

        public void MarkIsNucleotideSubstitutedChange(bool? value)
        {
            if (!HasIsNucleotideSubstitutedChange)
                _changes.Add(StructureElementVisualComponentPropertyContext.IsNucleotideSubstitutedPropertyKey, value);
            else
                _changes[StructureElementVisualComponentPropertyContext.IsNucleotideSubstitutedPropertyKey] = value;
        }

        public void ClearIsNucleotideSubstitutedChange()
        {
            if (HasIsNucleotideSubstitutedChange)
                _changes.Remove(StructureElementVisualComponentPropertyContext.IsNucleotideSubstitutedPropertyKey);
        }

        public void MarkNucleotideCircleDiameterChange(double? value)
        {
            if (!HasNucleotideCircleDiameterChange)
                _changes.Add(StructureElementVisualComponentPropertyContext.NucleotideCircleDiameterPropertyKey, value);
            else
                _changes[StructureElementVisualComponentPropertyContext.NucleotideCircleDiameterPropertyKey] = value;
        }

        public void ClearNucleotideCircleDiameterChange()
        {
            if (HasNucleotideCircleDiameterChange)
                _changes.Remove(StructureElementVisualComponentPropertyContext.NucleotideCircleDiameterPropertyKey);
        }

        public void MarkNucleotideCircleEdgeThicknessChange(double? value)
        {
            if (!HasNucleotideCircleEdgeThicknessChange)
                _changes.Add(StructureElementVisualComponentPropertyContext.NucleotideCircleEdgeThicknessPropertyKey, value);
            else
                _changes[StructureElementVisualComponentPropertyContext.NucleotideCircleEdgeThicknessPropertyKey] = value;
        }

        public void ClearNucleotideCircleEdgeThicknessChange()
        {
            if (HasNucleotideCircleEdgeThicknessChange)
                _changes.Remove(StructureElementVisualComponentPropertyContext.NucleotideCircleEdgeThicknessPropertyKey);
        }

        public void MarkNucleotideCircleIsFilledChange(bool? value)
        {
            if (!HasNucleotideCircleIsFilledChange)
                _changes.Add(StructureElementVisualComponentPropertyContext.NucleotideCircleIsFilledPropertyKey, value);
            else
                _changes[StructureElementVisualComponentPropertyContext.NucleotideCircleIsFilledPropertyKey] = value;
        }

        public void ClearNucleotideCircleIsFilledChange()
        {
            if (HasNucleotideCircleIsFilledChange)
                _changes.Remove(StructureElementVisualComponentPropertyContext.NucleotideCircleIsFilledPropertyKey);
        }

        public void MarkNucleotideCircleFillChange(Brush value)
        {
            if (!HasNucleotideCircleFillChange)
                _changes.Add(StructureElementVisualComponentPropertyContext.NucleotideCircleFillPropertyKey, value);
            else
                _changes[StructureElementVisualComponentPropertyContext.NucleotideCircleFillPropertyKey] = value;
        }

        public void ClearNucleotideCircleFillChange()
        {
            if (HasNucleotideCircleFillChange)
                _changes.Remove(StructureElementVisualComponentPropertyContext.NucleotideCircleFillPropertyKey);
        }

        public void MarkNucleotideCircleStrokeChange(Brush value)
        {
            if (!HasNucleotideCircleStrokeChange)
                _changes.Add(StructureElementVisualComponentPropertyContext.NucleotideCircleStrokePropertyKey, value);
            else
                _changes[StructureElementVisualComponentPropertyContext.NucleotideCircleStrokePropertyKey] = value;
        }

        public void ClearNucleotideCircleStrokeChange()
        {
            if (HasNucleotideCircleStrokeChange)
                _changes.Remove(StructureElementVisualComponentPropertyContext.NucleotideCircleStrokePropertyKey);
        }

        public void MarkNucleotideRenderingStyleChange(NucleotideRenderingMode? value)
        {
            if (!HasNucleotideRenderingStyleChange)
                _changes.Add(StructureElementVisualComponentPropertyContext.NucleotideRenderingStylePropertyKey, value);
            else
                _changes[StructureElementVisualComponentPropertyContext.NucleotideRenderingStylePropertyKey] = value;
        }

        public void ClearNucleotideRenderingStyleChange()
        {
            if (HasNucleotideRenderingStyleChange)
                _changes.Remove(StructureElementVisualComponentPropertyContext.NucleotideRenderingStylePropertyKey);
        }

        public void MarkBasePairConnectorIsFilledChange(bool? value)
        {
            if (!HasBasePairConnectorIsFilledChange)
                _changes.Add(StructureElementVisualComponentPropertyContext.BasePairConnectorIsFilledPropertyKey, value);
            else
                _changes[StructureElementVisualComponentPropertyContext.BasePairConnectorIsFilledPropertyKey] = value;
        }

        public void ClearBasePairConnectorIsFilledChange()
        {
            if (HasBasePairConnectorIsFilledChange)
                _changes.Remove(StructureElementVisualComponentPropertyContext.BasePairConnectorIsFilledPropertyKey);
        }

        public void MarkBasePairConnectorIsVisibleChange(bool? value)
        {
            if (!HasBasePairConnectorIsVisibleChange)
                _changes.Add(StructureElementVisualComponentPropertyContext.BasePairConnectorIsVisiblePropertyKey, value);
            else
                _changes[StructureElementVisualComponentPropertyContext.BasePairConnectorIsVisiblePropertyKey] = value;
        }

        public void ClearBasePairConnectorIsVisibleChange()
        {
            if (HasBasePairConnectorIsVisibleChange)
                _changes.Remove(StructureElementVisualComponentPropertyContext.BasePairConnectorIsVisiblePropertyKey);
        }

        public void MarkBasePairConnectorFillChange(Brush value)
        {
            if (!HasBasePairConnectorFillChange)
                _changes.Add(StructureElementVisualComponentPropertyContext.BasePairConnectorFillPropertyKey, value);
            else
                _changes[StructureElementVisualComponentPropertyContext.BasePairConnectorFillPropertyKey] = value;
        }

        public void ClearBasePairConnectorFillChange()
        {
            if (HasBasePairConnectorFillChange)
                _changes.Remove(StructureElementVisualComponentPropertyContext.BasePairConnectorFillPropertyKey);
        }

        public void MarkBasePairConnectorStrokeChange(Brush value)
        {
            if (!HasBasePairConnectorStrokeChange)
                _changes.Add(StructureElementVisualComponentPropertyContext.BasePairConnectorStrokePropertyKey, value);
            else
                _changes[StructureElementVisualComponentPropertyContext.BasePairConnectorStrokePropertyKey] = value;
        }

        public void ClearBasePairConnectorStrokeChange()
        {
            if (HasBasePairConnectorStrokeChange)
                _changes.Remove(StructureElementVisualComponentPropertyContext.BasePairConnectorStrokePropertyKey);
        }

        public void MarkBasePairConnectorSizeChange(double? value)
        {
            if (!HasBasePairConnectorSizeChange)
                _changes.Add(StructureElementVisualComponentPropertyContext.BasePairConnectorSizePropertyKey, value);
            else
                _changes[StructureElementVisualComponentPropertyContext.BasePairConnectorSizePropertyKey] = value;
        }

        public void ClearBasePairConnectorSizeChange()
        {
            if (HasBasePairConnectorSizeChange)
                _changes.Remove(StructureElementVisualComponentPropertyContext.BasePairConnectorSizePropertyKey);
        }

        public void MarkBasePairConnectorStrokeThicknessChange(double? value)
        {
            if (!HasBasePairConnectorStrokeThicknessChange)
                _changes.Add(StructureElementVisualComponentPropertyContext.BasePairConnectorStrokeThicknessPropertyKey, value);
            else
                _changes[StructureElementVisualComponentPropertyContext.BasePairConnectorStrokeThicknessPropertyKey] = value;
        }

        public void ClearBasePairConnectorStrokeThicknessChange()
        {
            if (HasBasePairConnectorStrokeThicknessChange)
                _changes.Remove(StructureElementVisualComponentPropertyContext.BasePairConnectorStrokeThicknessPropertyKey);
        }

        public void MarkBasePairConnectorRenderingStyleChange(BasePairConnectorRenderingMode? value)
        {
            if (!HasBasePairConnectorRenderingStyleChange)
                _changes.Add(StructureElementVisualComponentPropertyContext.BasePairConnectorRenderingStylePropertyKey, value);
            else
                _changes[StructureElementVisualComponentPropertyContext.BasePairConnectorRenderingStylePropertyKey] = value;
        }

        public void ClearBasePairConnectorRenderingStyleChange()
        {
            if (HasBasePairConnectorRenderingStyleChange)
                _changes.Remove(StructureElementVisualComponentPropertyContext.BasePairConnectorRenderingStylePropertyKey);
        }

        public void MarkVisibilityChange(bool visibility)
        {
            _visible = visibility;
        }

        public StructureElementPropertyChangeSet(bool visibility)
        {
            _changes = new Dictionary<string, object>();
            _visible = visibility;
        }

        private Dictionary<string, object> _changes;
        private bool _visible;
    }
}
